Skip to content

[JLArrays] Support KernelAbstractions 0.10 - #826

Merged
maleadt merged 7 commits into
mainfrom
jlka0.10
Nov 6, 2026
Merged

maleadt merged 7 commits into
mainfrom
jlka0.10

Conversation

@christiangnrd

@christiangnrd christiangnrd commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

JLArrays, the CPU reference back-end used to test GPUArrays and downstream packages without a GPU, still targets KernelAbstractions 0.9. The vendor back-ends (CUDA, AMDGPU, Metal, oneAPI, OpenCL) have moved to KernelAbstractions 0.10, which builds on KernelInterface, so a test environment using JLArrays can't move along with them.

This ports JLArrays to KernelAbstractions 0.10 and drops 0.9. JLBackend becomes a KernelInterface back-end in the same shape as the vendor ports: it converts arguments to POCL device arrays and forwards compilation, launches and device queries to KernelAbstractions' POCL back-end, which is what runs KA 0.10 kernels on the CPU. The KernelAbstractions and KernelInterface testsuites now run on JLArrays, skipping the same POCL-only tests the vendor back-ends skip.

JLArrays used to reduce, sort, scan and search with Base on an Array wrapping its storage, because AcceleratedKernels' kernels did not run on its KA 0.9 back-end. They do now, so JLArrays takes the same AcceleratedKernels code paths as the GPU back-ends instead of bypassing them. This is also what makes those operations work on arrays of isbits unions, which the testsuite requires since #835: an Array can't wrap their storage, while POCL's device arrays (as of KernelAbstractions 0.10.5) read the selector bytes JLArrays keeps after the data. The cost is test time, as every operation now compiles a kernel: the reduction, sorting and scan testsets take about twice as long.

Along the way:

  • convert.(T, ::JLArray) failed to compile, because JLArrays wrapped Refs before POCL could recognize a Ref of a type. JLArrays now converts only what the Ref holds.
  • JLArray kernels compute indices in Int like POCL's own, instead of the Int32 KernelAbstractions uses on GPUs, which keeps LLVM from vectorizing over work-items (~7% on a 2048×2048 element-wise kernel).
  • Arguments are converted without allocating per launch (c .= a .+ b goes from 1344 to 480 bytes).

This is breaking, hence JLArrays 0.5: JLBackend(; static) is gone, since KA 0.10's CPU back-end has no static scheduling, and so is JLDeviceArray (JLArrays are POCL CLDeviceArrays in kernels). POCL's SPIR-V back-end cannot lower 128-bit integers, so Int128 is no longer tested with JLArrays.

The macOS runners, which run tests one at a time, were already close to the 60-minute job limit, so the limit is raised to 90 minutes.

@christiangnrd

christiangnrd commented Oct 21, 2026 •

Copy link
Copy Markdown
Member Author

I bumped CI timeout to 90 minutes since the POCL backend of KA 0.10 increases testsuite runtime and the macOS runners with only 1 job were right on the edge (either side)

I cancelled the latest Buildkite run since the GHA timeout increase was the only change since the last successful run.

@christiangnrd

Copy link
Copy Markdown
Member Author

Not sure this is the best approach but Claude redesigned the JLArrays storage to support bits union.

@maleadt

maleadt commented Oct 31, 2026

Copy link
Copy Markdown
Member

Did you rebase out my changes? Looking at your force push, you went from https://github.com/JuliaGPU/GPUArrays.jl/commits/784d123d40e549406b292c57a61bfb1fe6c1d5ed/ to https://github.com/JuliaGPU/GPUArrays.jl/commits/764ad56eba1db4cf6a617083edf2ccaaea145ede/, which lacks the result of my rework last week (as reflected by the edited top post).

@christiangnrd

Copy link
Copy Markdown
Member Author

I think I might have I missed the rework. The commit is probably still on my laptop I’ll revert my changes in a few hours.

@maleadt

maleadt commented Oct 31, 2026

Copy link
Copy Markdown
Member

No worries. Maybe just have your Claude session incorporate those changes? It cleaned-up the implementation a bit, too.

@christiangnrd

christiangnrd commented Oct 31, 2026 •

Copy link
Copy Markdown
Member Author

Ok I had Claude recover your changes, rebase, and then reincorporate the storage backing I'm unsure about.

Tests should pass once KA cpu backend has bitsunion support

@maleadt maleadt changed the title [JLArrays] Support KA 0.10 [JLArrays] Support KernelAbstractions 0.10 Nov 5, 2026
@maleadt

maleadt commented Nov 5, 2026

Copy link
Copy Markdown
Member

I reworked this together with #827, now that KernelAbstractions 0.10.5 is out (with JuliaGPU/KernelAbstractions.jl#944).

I dropped the Vector{T} storage commit. Main's byte layout already keeps the selector bytes after the data, which is where POCL's device arrays (as of 0.10.5) look for them, so kernels only need maxsize pointing there. The part that really needed Vector{T} storage was JLArrays' host fallbacks for reductions, sorting, scans and findall, which wrap the storage in an Array. Those only existed because AcceleratedKernels' kernels didn't run on JLBackend under KA 0.9. They do now, so I removed the fallbacks and JLArrays takes the same AK paths as the GPU back-ends. That fixes the union tests, and in an earlier measurement it also cut using JLArrays from about 4.4 s to 0.6 s. The cost is test time: the reduction and scan testsets take about twice as long, which the 90-minute timeout should absorb.

On #827: I kept the KernelInterface port and the padding removal (2048² Float32 matmul on an RTX 5080: 5.1 ms → 3.5 ms; the PTX only uses vector shared loads without the padding). I dropped the -zero accumulator and the 1:min(TILE, K - k0) loop. The loop made the kernel about 7% slower, and Base's matmul returns +0.0 for [-0.0;;] * [1.0;;] on Julia 1.10–1.13 (only 1.15-DEV gives -0.0), so the -0.0 change can be a follow-up once LinearAlgebra settles.

@christiangnrd

Copy link
Copy Markdown
Member Author

Nice! I didn't like that workaround at all.

Regarding #827, once that's merged and we have a version of KI.barrier that doesn't require the device memory flag it'll be identical to the Metal.jl scalar kernel so we'll be able to deprecate that one

With KernelAbstractions 0.10, JLArray kernels run on its POCL back-end.
Drop the KA 0.9 code paths, including JLDeviceArray, and convert
JLArrays to POCL device arrays. Leave `Ref`s to POCL's conversion after
converting their contents, so that `Ref`s of types, as passed by
`convert.(T, A)`, are handled too. POCL's SPIR-V back-end cannot lower
128-bit integers, so stop testing Int128 with JLArrays.
christiangnrd and others added 6 commits November 5, 2026 18:26
Make JLBackend a KernelInterface back-end, like the GPU back-ends that
moved to KernelAbstractions 0.10: it converts arguments to POCL's and
forwards compilation, launches and device queries to the POCL back-end.
Run the KernelAbstractions and KernelInterface testsuites on it, skipping
the dense-to-sparse test, which JLArrays don't support, and the tests
that only exercise KernelAbstractions' own CPU back-end.

KA 0.10's CPU back-end has no static scheduling anymore, so this removes
the `static` option of JLBackend.
KernelAbstractions narrows `@index` computations to Int32 on every
back-end but POCL, because on POCL the narrowing keeps LLVM from
vectorizing the loops over work-items. JLArray kernels run on POCL, but
JLBackend isn't a POCLBackend, so they got Int32 indices. Using Int
speeds up a 2048x2048 element-wise kernel by about 7%.
A JLArray was converted to a POCL device array by wrapping its memory in
an Array and adapting that with a fresh KernelAdaptor, allocating both on
every conversion, which happens several times per argument per launch.
Construct the device array from the JLArray's pointer instead. This
reduces the allocations of `c .= a .+ b` from 1344 to 480 bytes.

This also converts arrays of isbits unions, whose storage an `Array`
can't wrap: POCL's device arrays find their selector bytes `maxsize`
bytes past the data, so point that at the JLArray's own.
JLArrays reduced, sorted, scanned and searched with Base on an `Array`
wrapping its storage, because AcceleratedKernels' kernels did not run on
its KA 0.9 back-end. On KA 0.10 they run through POCL like any other
kernel, so JLArrays now takes the same code paths as the GPU back-ends
instead of bypassing them.

This also makes these operations work on arrays of isbits unions: an
`Array` can't wrap their storage, whose selector bytes follow the data,
while POCL arrays can.
The port to KernelAbstractions 0.10 is breaking: `JLBackend(; static)`
and `JLDeviceArray` are gone.
The KernelAbstractions and KernelInterface testsuites, and kernels for
every reduction, sort and scan, make JLArrays' tests slower. The macOS
runners, which run one test at a time, were already close to the
60-minute limit.
@maleadt
maleadt merged commit 30df35e into main Nov 6, 2026
9 checks passed
@maleadt
maleadt deleted the jlka0.10 branch November 6, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants